package org.lgiavedoni.android.franq.service.event;

import java.util.ArrayList;
import java.util.List;
import java.util.Observer;

import org.lgiavedoni.android.franq.core.envent.Event;
import org.lgiavedoni.android.franq.core.envent.dao.EventDao;
import org.lgiavedoni.android.franq.core.service.Service;
import org.lgiavedoni.android.franq.event.FrankStartEvent;
import org.lgiavedoni.android.franq.service.log.Logger;

public class EventService extends Service {

	public static final EventService inst = new EventService();
	private final List<Observer> observers = new ArrayList<Observer>();
	private static final String IMPLEMENTATIONS_KEY = "eventListeners";
	private final EventDao eventDao = EventDao.inst;

	private EventService() {
	}

	@Override
	public String getServiceName() {
		return "events";
	}

	@Override
	protected void startInternal() {
		for (Object obj : getImplementations(IMPLEMENTATIONS_KEY)) {
			observers.add((Observer) obj);
		}
		for (Observer obj : observers) {
			super.addObserver(obj);
		}
		EventService.inst.fireEvent(new FrankStartEvent());
	}

	@Override
	protected void stopInternal() {
		observers.clear();
		for (Observer obj : observers) {
			this.deleteObserver(obj);
		}
	}

	@Override
	public void _run() {
	}

	@Override
	public void addObserver(Observer observer) {
		observers.add(observer);
		if (isStarted())
			super.addObserver(observer);
	}

	public void removeObserver(Observer observer) {
		observers.remove(observer);
		super.deleteObserver(observer);
	}

	public void fireEvent(final Event event) {
		if (isStarted()) {
			new Thread() {
				@Override
				public void run() {
					eventDao.add(event);
					setChanged();
					notifyObservers(event);
				}
			}.start();
		} else {
			Logger.inst.warning("Event [" + event + "] has been rejected. The Event Service is not running");
		}
	}
}
